package com.collection.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class PerformanceReportGenerator {
    private static final Logger logger = LoggerFactory.getLogger(PerformanceReportGenerator.class);
    private static final String REPORT_DIR = "target/performance-reports";
    private static final Map<String, List<PerformanceMetric>> metrics = new ConcurrentHashMap<>();

    public static void recordMetric(String testName, String operation, long duration) {
        metrics.computeIfAbsent(testName, k -> new ArrayList<>())
                .add(new PerformanceMetric(operation, duration));
    }

    public static void generateReport() {
        try {
            createReportDirectory();
            String reportPath = generateHtmlReport();
            logger.info("性能测试报告已生成: {}", reportPath);
        } catch (IOException e) {
            logger.error("生成性能测试报告失败", e);
        }
    }

    private static void createReportDirectory() throws IOException {
        Path path = Paths.get(REPORT_DIR);
        if (!Files.exists(path)) {
            Files.createDirectories(path);
        }
    }

    private static String generateHtmlReport() throws IOException {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String reportPath = REPORT_DIR + "/performance_report_" + timestamp + ".html";
        
        try (FileWriter writer = new FileWriter(reportPath)) {
            writer.write(generateHtmlContent());
        }
        
        return reportPath;
    }

    private static String generateHtmlContent() {
        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html>\n")
            .append("<html>\n")
            .append("<head>\n")
            .append("    <title>Java集合框架性能测试报告</title>\n")
            .append("    <script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n")
            .append("    <style>\n")
            .append("        body { font-family: Arial, sans-serif; margin: 20px; }\n")
            .append("        .chart-container { width: 800px; margin: 20px auto; }\n")
            .append("        table { border-collapse: collapse; width: 100%; margin: 20px 0; }\n")
            .append("        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }\n")
            .append("        th { background-color: #f2f2f2; }\n")
            .append("    </style>\n")
            .append("</head>\n")
            .append("<body>\n")
            .append("    <h1>Java集合框架性能测试报告</h1>\n")
            .append("    <p>生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("</p>\n");

        // 生成图表
        html.append("    <div class=\"chart-container\">\n")
            .append("        <canvas id=\"performanceChart\"></canvas>\n")
            .append("    </div>\n");

        // 生成表格
        html.append("    <h2>详细性能数据</h2>\n")
            .append("    <table>\n")
            .append("        <tr>\n")
            .append("            <th>测试名称</th>\n")
            .append("            <th>操作类型</th>\n")
            .append("            <th>耗时(纳秒)</th>\n")
            .append("        </tr>\n");

        for (Map.Entry<String, List<PerformanceMetric>> entry : metrics.entrySet()) {
            for (PerformanceMetric metric : entry.getValue()) {
                html.append("        <tr>\n")
                    .append("            <td>").append(entry.getKey()).append("</td>\n")
                    .append("            <td>").append(metric.operation).append("</td>\n")
                    .append("            <td>").append(metric.duration).append("</td>\n")
                    .append("        </tr>\n");
            }
        }

        html.append("    </table>\n");

        // 添加JavaScript代码生成图表
        html.append("    <script>\n")
            .append("        const ctx = document.getElementById('performanceChart').getContext('2d');\n")
            .append("        new Chart(ctx, {\n")
            .append("            type: 'bar',\n")
            .append("            data: {\n")
            .append("                labels: ").append(generateChartLabels()).append(",\n")
            .append("                datasets: ").append(generateChartDatasets()).append("\n")
            .append("            },\n")
            .append("            options: {\n")
            .append("                responsive: true,\n")
            .append("                scales: {\n")
            .append("                    y: {\n")
            .append("                        beginAtZero: true,\n")
            .append("                        title: {\n")
            .append("                            display: true,\n")
            .append("                            text: '耗时(纳秒)'\n")
            .append("                        }\n")
            .append("                    }\n")
            .append("                }\n")
            .append("            }\n")
            .append("        });\n")
            .append("    </script>\n")
            .append("</body>\n")
            .append("</html>");

        return html.toString();
    }

    private static String generateChartLabels() {
        List<String> labels = new ArrayList<>();
        for (Map.Entry<String, List<PerformanceMetric>> entry : metrics.entrySet()) {
            for (PerformanceMetric metric : entry.getValue()) {
                labels.add(entry.getKey() + " - " + metric.operation);
            }
        }
        return labels.toString();
    }

    private static String generateChartDatasets() {
        List<Map<String, Object>> datasets = new ArrayList<>();
        Map<String, Object> dataset = new ConcurrentHashMap<>();
        dataset.put("label", "性能测试结果");
        
        List<Long> data = new ArrayList<>();
        for (List<PerformanceMetric> metricsList : metrics.values()) {
            for (PerformanceMetric metric : metricsList) {
                data.add(metric.duration);
            }
        }
        dataset.put("data", data);
        dataset.put("backgroundColor", "rgba(54, 162, 235, 0.5)");
        dataset.put("borderColor", "rgba(54, 162, 235, 1)");
        dataset.put("borderWidth", 1);
        
        datasets.add(dataset);
        return datasets.toString();
    }

    private static class PerformanceMetric {
        final String operation;
        final long duration;

        PerformanceMetric(String operation, long duration) {
            this.operation = operation;
            this.duration = duration;
        }
    }
} 